#include<iostream>
#include<vector>
#include<unistd.h>
#include<cstring>
using namespace std ;

#define NUM 4 

// struct threadData
// {
//     string tid ;
//     string threadname;
// };
//  string toHex(pthread_t tid)

// {
//     //将tid转为16进制
// char buffer[128] ;
// snprintf( buffer ,sizeof(buffer) , "0x%x", tid) ;
// return buffer ;     
// }
// void *threadRoutine(void *args)
// {
// threadData * td = (threadData * )args;
//         int i = 0;
//         int test_i = 0;
//     while (i <NUM)
//     {
      
//         cout << "pid: " << getpid() << " tid : "
//             << toHex(pthread_self() ) << ", threadname: " << td->threadname 
//              <<", test_i :"<<test_i
//              <<", &test_i :" <<toHex(  (pthread_t) &test_i)<<endl;
//                sleep(1) ;
//             i++,test_i ++ ;
//     }

//         delete td;
//     return nullptr ;

// }
//  void InitThreadData  ( threadData * td , int number )
// {
// td->threadname = "thread-" + to_string( number) ;


// }

// int main()
// { 
//     //创建一批线程
//     vector<pthread_t  > tids ;
//     for(int i =0 ; i < NUM ;i++)
//     {
//        // sleep(1) ;
//         pthread_t tid ;
//         //线程是共享堆的
//         threadData * td =new threadData  ;

//              InitThreadData(td, i);
//         pthread_create(&tid , nullptr , threadRoutine,td );
//         tids.push_back(tid) ;
//     }
   
//    //将这一批线程等待
//     for( int i =0 ; i <tids.size() ; i++)
//     {
//         pthread_join(tids[i] , nullptr) ;
//     }
//     return 0 ;
// }



// //线程局部存储

//   __thread  int g_val= 100;  //  __是编译选项  ，将g_val这个变量设为线程的私有的全局变量

// struct threadData
// {
//     string tid ;
//     string threadname;
// };
//  string toHex(pthread_t tid)

// {
//     //将tid转为16进制
// char buffer[128] ;
// snprintf( buffer ,sizeof(buffer) , "0x%x", tid) ;
// return buffer ;     
// }
// void *threadRoutine(void *args)
// {

//     int i = 0;
// threadData * td = (threadData * )args;

//     while (i <NUM)
//     {
      
//      cout << "pid: " << getpid() << ", tid : "<<toHex(pthread_self() )
//        << ", threadname: " << td->threadname
//          << ", g_val: " << g_val << " ,&g_val: " << &g_val <<endl;
//                sleep(1) ;  
//             i++,g_val++;
//     } 

//         delete td;
//     return nullptr ;

// }
//  void InitThreadData  ( threadData * td , int number )
// {
// td->threadname = "thread-" + to_string( number) ;


// }

// int main()
// { 
//     //创建一批线程
//     vector<pthread_t  > tids ;
//     for(int i =0 ; i < NUM ;i++)
//     {
//        // sleep(1) ;
//         pthread_t tid ;
//         //线程是共享堆的
//         threadData * td =new threadData  ;

//              InitThreadData(td, i);
//         pthread_create(&tid , nullptr , threadRoutine,td );
//         tids.push_back(tid) ;
//     }

//         sleep(1) ;

    

//    //将这一批线程等待
//     for( int i =0 ; i <tids.size() ; i++)
//     {
//         pthread_join(tids[i] , nullptr) ;
//     }
//     return 0 ;
// }



// //线程局部存储

//   __thread  int g_val= 100;  //  __是编译选项  ，将g_val这个变量设为线程的私有的全局变量

// struct threadData
// {
//     string tid ;
//     string threadname;
// };
//  string toHex(pthread_t tid)

// {
//     //将tid转为16进制
// char buffer[128] ;
// snprintf( buffer ,sizeof(buffer) , "0x%x", tid) ;
// return buffer ;     
// }
// void *threadRoutine(void *args)
// {
//     //线程分离
//     pthread_detach(pthread_self());
//     int i = 0;
// threadData * td = (threadData * )args;

//     while (i <NUM)
//     {
      
//     //  cout << "pid: " << getpid() << ", tid : "<<toHex(pthread_self() )
//     //    << ", threadname: " << td->threadname
//     //      << ", g_val: " << g_val << " ,&g_val: " << &g_val <<endl;
//                sleep(1) ;  
//             i++,g_val++;
//     } 

//         delete td;
//     return nullptr ;

// }
//  void InitThreadData  ( threadData * td , int number )
// {
// td->threadname = "thread-" + to_string( number) ;


// }

// int main()
// { 
//     //创建一批线程
//     vector<pthread_t  > tids ;
//     for(int i =0 ; i < NUM ;i++)
//     {
//        // sleep(1) ;
//         pthread_t tid ;
//         //线程是共享堆的
//         threadData * td =new threadData  ;

//              InitThreadData(td, i);
//         pthread_create(&tid , nullptr , threadRoutine,td );
//         tids.push_back(tid) ;
//     }

//         sleep(1) ;

    

//    //将这一批线程等待
//     for( int i =0 ; i <tids.size() ; i++)
//     {
//         //线程分离后，不能被等待的
//        int n = pthread_join(tids[i], nullptr);
//         printf("n = %d, who = 0x%x, why: %s\n", n, tids[i], strerror(n));
//     }
//     return 0 ;
// }




int tickets = 1000; // 票
class threadData
{
        public:
        threadData ( int number ) 
        {
                 threadname = "thread-" + to_string(number);
        }

public:
    string  threadname ;  //线程名
} ;

void * getTicket (void *args )
{

            threadData *td = (threadData * ) args ;
            const char *  name = td->threadname.c_str() ;
            while(true ) 
            {
                if(tickets > 0) 
                {
                      usleep(1000);
                       printf("who=%s, get a ticket: %d\n", name, tickets);
                    tickets --;

                }
                else 
                break; 
            }
              printf("%s ... quit\n", name);
            return  nullptr ;

}
int main()
{
    vector<pthread_t> tids; 
    vector<threadData *> thread_datas;  
    // thread_datas.resize(100000);
    //  tids.resize(100000);
    //模拟多线程抢票 
      for (int i = 1; i <= NUM; i++)
     {
         threadData * td   = new threadData (i);
        pthread_t tid ;
          thread_datas.push_back(td);
        pthread_create(&tid , nullptr ,getTicket , thread_datas[i-1]);
        tids.push_back(tid) ;

     

    
     }


     //线程等待
      for (auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }

  for (auto td : thread_datas)
    {
        delete td;
    }
    return 0 ;
}